﻿namespace SAD.DataCenter
{
    using System;
    using System.Linq;
    using System.Data.Objects;
    using System.Collections.Generic;
    using SAD.Common.Models;
    using System.ServiceModel;
    using SAD.Common.Enums;
    using System.ServiceModel.Channels;

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class ShowNodeManagerService : SAD.Common.Contracts.DataCenter.IShowNodeManager
    {
        #region IShowNodeManager 成员

        ShowNode_Data SAD.Common.Contracts.DataCenter.IShowNodeManager.GetShowNodeData(string showNodeMark)
        {
            return ShowNodeManager.Instance.GetShowNodeData(showNodeMark);
        }

        ShowNode_Data SAD.Common.Contracts.DataCenter.IShowNodeManager.SetOnline(string showNodeMark, string hostUri)
        {
            return ShowNodeManager.Instance.SetOnline(showNodeMark, hostUri);
        }

        void SAD.Common.Contracts.DataCenter.IShowNodeManager.SetOffline(string showNodeMark)
        {
            ShowNodeManager.Instance.SetOffline(showNodeMark);
        }

        string SAD.Common.Contracts.DataCenter.IShowNodeManager.GetShowNodeIP()
        {
            return ShowNodeManager.Instance.GetShowNodeIP();
        }
        #endregion
    }

    public class ShowNodeManager
    {
        #region Instance
        /// <summary>
        /// 类型单例
        /// </summary>
        public static ShowNodeManager Instance
        {
            get
            {
                return m_Instance;
            }
        }
        private static ShowNodeManager m_Instance = new ShowNodeManager();
        #endregion

        public List<ShowNode_Data> OnlineShowNodes
        {
            get
            {
                if (m_OnlineShowNodes == null)
                {
                    lock (syncOnlineShowNodes)
                    {
                        if (m_OnlineShowNodes == null)
                        {
                            m_OnlineShowNodes = new List<ShowNode_Data>();
                            ShowNode_Data[] tmp = GetOnlineShowNodeDatas();
                            if (tmp != null && tmp.Length > 0)
                            {
                                m_OnlineShowNodes.AddRange(tmp);
                            }
                        }
                    }
                }
                return m_OnlineShowNodes;
            }
        }
        private List<ShowNode_Data> m_OnlineShowNodes = null;
        private object syncOnlineShowNodes = new object();

        private ShowNodeManager()
        {
        }

        public ShowNode_Data SetOnline(string showNodeMark, string hostUri)
        {
            ShowNode_Data showNode = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                showNode = ctx.ShowNode_Datas.FirstOrDefault<ShowNode_Data>(it => it.Mark == showNodeMark);
                if (showNode != null)
                {
                    showNode.OnlineStatus = (byte)ShowNode_OnlineStatus.Online;
                    showNode.HostUri = hostUri;
                    ctx.SaveChanges();
                }
            }

            //更新缓冲
            int index = -1;
            for (int i = 0; i < OnlineShowNodes.Count; i++)
            {
                if (OnlineShowNodes[i].Mark == showNodeMark)
                {
                    index = i;
                }
            }
            if (index > -1)
            {
                OnlineShowNodes[index] = showNode;
            }
            else
            {
                OnlineShowNodes.Add(showNode);
            }

            return showNode;
        }

        public void SetOffline(string showNodeMark)
        {
            ShowNode_Data showNode = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                showNode = ctx.ShowNode_Datas.FirstOrDefault<ShowNode_Data>(it => it.Mark == showNodeMark);
                if (showNode != null)
                {
                    showNode.OnlineStatus = (byte)ShowNode_OnlineStatus.Offine;
                    ctx.SaveChanges();
                }
            }

            //更新缓冲
            int index = -1;
            for (int i = 0; i < OnlineShowNodes.Count; i++)
            {
                if (OnlineShowNodes[i].Mark == showNodeMark)
                {
                    index = i;
                }
            }
            if (index> -1)
            {
                OnlineShowNodes[index] = showNode;
            }
            else
            {
                OnlineShowNodes.Add(showNode);
            }
        }

        public ShowNode_Data GetShowNodeData(int id)
        {
            ShowNode_Data result = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                result = ctx.ShowNode_Datas.First<ShowNode_Data>(it => it.ID == id);
            }

            return result;
        }

        public ShowNode_Data GetShowNodeData(string showNodeMark)
        {
            ShowNode_Data result = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                result = ctx.ShowNode_Datas.First<ShowNode_Data>(it => it.Mark == showNodeMark);
            }

            return result;
        }

        public ShowNode_Data[] GetAllShowNodeDatas()
        {
            ShowNode_Data[] result = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                result = ctx.ShowNode_Datas.ToArray();
            }

            return result;
        }

        public string GetShowNodeIP()
        {
            OperationContext context = OperationContext.Current;
            MessageProperties essageProperties = context.IncomingMessageProperties;
            RemoteEndpointMessageProperty endpointProperty = essageProperties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;

            return endpointProperty.Address;
        }


        private ShowNode_Data[] GetOnlineShowNodeDatas()
        {
            ShowNode_Data[] result = null;
            using (SAD_Modles ctx = new SAD_Modles())
            {
                var q = from r in ctx.ShowNode_Datas
                        where r.OnlineStatus == (byte)ShowNode_OnlineStatus.Online
                        select r;

                result = q.ToArray();
            }

            return result;
        }
    }
}